
package com.wlstock.funi.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.VolleyError;
import com.em.mission.Mission;
import com.em.mission.MissionQueue;
import com.em.mission.MissionResultListener;
import com.wlstock.funi.MissionInstance.BuyXinMission;
import com.wlstock.funi.MissionInstance.KLineMissionQueue;
import com.wlstock.funi.MissionInstance.MarketStaticMission;
import com.wlstock.funi.MissionInstance.MissionNameConstant;
import com.wlstock.funi.MissionInstance.MoneyFlowStaMission;
import com.wlstock.funi.MissionInstance.StrategyMission;
import com.wlstock.funi.MissionInstance.WanLongStaMission;
import com.wlstock.funi.MissionInstance.YiMengPositionMission;
import com.wlstock.funi.MissionInstance.ZDFMission;
import com.wlstock.funi.R;
import com.wlstock.funi.app.FundApplication;
import com.wlstock.funi.app.FundAsyTask;
import com.wlstock.funi.app.FundAsyTask.TaskLitener;
import com.wlstock.funi.constant.SharePrefConstants;
import com.wlstock.funi.dao.AIAccountDao;
import com.wlstock.funi.dao.MyAccountStockDao;
import com.wlstock.funi.dao.PositionDao;
import com.wlstock.funi.dao.SelfFundDao;
import com.wlstock.funi.dao.SelfFundSetDao;
import com.wlstock.funi.dao.StrategyFundSelDao;
import com.wlstock.funi.fundenum.TRADE_ERROR_STATE;
import com.wlstock.funi.model.AIAccountsModel;
import com.wlstock.funi.model.MyAccountStocks;
import com.wlstock.funi.model.OperateModel;
import com.wlstock.funi.model.PositionModel;
import com.wlstock.funi.model.SelfFundHisModel;
import com.wlstock.funi.model.SelfFundModel;
import com.wlstock.funi.model.SelfFundSetModel;
import com.wlstock.funi.model.StrategyFundModel;
import com.wlstock.funi.request.EventBusConstants;
import com.wlstock.funi.request.NetWorkListener;
import com.wlstock.funi.request.SinaPriceRequest;
import com.wlstock.funi.runnable.CurPosition;
import com.wlstock.funi.runnable.RefreshLogSession;
import com.wlstock.funi.utils.BuyHelper;
import com.wlstock.funi.utils.CaculateUtils;
import com.wlstock.funi.utils.GlobalIndexHelper;
import com.wlstock.funi.utils.MyOwnStockManager;
import com.wlstock.funi.utils.NotiIdGenerator;
import com.wlstock.funi.utils.NotiUtils;
import com.wlstock.funi.utils.SharePreferenceUtils;
import com.wlstock.funi.utils.StockUtils;
import com.wlstock.funi.utils.TimeUtils;
import com.wlstock.funi.utils.ToastUtils;
import com.wlstock.funi.utils.TradeManagerListener;
import com.wlstock.funi.utils.TradeSetUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.Date;
import java.util.List;

import static com.wlstock.funi.MissionInstance.MissionNameConstant.MISSION_STRATEGY;
import static com.wlstock.funi.utils.SharePreferenceUtils.getBoolSP;

public class LatestPriceService extends Service implements NetWorkListener, MissionResultListener, MissionQueue.onMissionQueueListener, CurPosition.CurPositionListener, TradeManagerListener, RefreshLogSession.ResultListener {

	private final IBinder myBinder = new LatestPriceServiceBinder();
	private SinaPriceRequest curStockRequest;
	private List<SelfFundModel> fundModels;
	private NetWorkListener listener;
	private boolean isInRange;
	private String isRecord;

	private MissionQueue staMissions;
	private KLineMissionQueue kLineMissions;
	private String marketTitle = "";
	private String marketContent = "";
	private MoneyFlowStaMission moneyFlowStaMission;
	private MarketStaticMission marketStaticMission;


	@Override
	public IBinder onBind(Intent arg0) {
		Toast.makeText(this, "onBind LatestPriceService", Toast.LENGTH_SHORT).show();
		return myBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		curStockRequest = new SinaPriceRequest();
		isInRange = false;
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
		boolean isDebugMode = SharePreferenceUtils.getBoolSP(this,SharePrefConstants.IS_DEBUG_MODE,false);
		//非调试模式下判断是否在盘中
		if (!isDebugMode){
			isInRange = TimeUtils.isHourInRange("09:15","15:10",new Date());
		}else {
			isInRange = true;
		}
		if (isInRange) {
			FundApplication.requestPrice++;
			//10秒启动一次 6次一分钟， 默认每3分钟播报一下价格，可以设置
			if (FundApplication.requestPrice % (6*TradeSetUtils.getVoiceDis(this)) ==0) {
				FundApplication.requestPrice = 0;
				isRecord = "Y";
				Log.i("TAG", "isRecord Y");

				//统计的任务
				reqStaMissions();
				//市场概况
				reqMarketStaMission();
				//获取当前持仓
				reqKeepedPosition();
				//获取K线数据
				reqKlineData();
			}else {
				Log.i("TAG", "isRecord N");
				isRecord = "N";
			}
			
			if (this.listener != null) {
				curStockRequest.listener = this.listener;
			}else{
				curStockRequest.listener = this;
				getNewlyFundModels();
			}
			
			List<String> tmpStockNoList = StockUtils.parseSelfFundStkNos(fundModels);			
			if (tmpStockNoList != null && !tmpStockNoList.isEmpty() &&fundModels.size() == tmpStockNoList.size()) {
				curStockRequest.request(tmpStockNoList, EventBusConstants.EVENT_STOCKS_UPDATE_MUTI_PRICE);
			}
		}

		//获取问股策略中的数据并且存放
		if (TimeUtils.isHourInRange("14:50","15:00",new Date()) ){
			StrategyMission.getInstance(LatestPriceService.this,MissionNameConstant.MISSION_STRATEGY).start(MISSION_STRATEGY,LatestPriceService.this);
		}

		if (TimeUtils.isHourInRange("10:30","11:30",new Date())){
            BuyXinMission buyXinMission = BuyXinMission.getInstance(LatestPriceService.this,MissionNameConstant.MISSION_BUYXIN);
            buyXinMission.start(this);
        }

		reqMoneyFlow();
		BuyHelper.getInstance(this).autoBuy(SharePreferenceUtils.getBoolSP(this, SharePrefConstants.IS_AUTO_BUY_MODE,false),this);
	}

	private void reqKlineData() {
		if (kLineMissions == null){
			kLineMissions =  KLineMissionQueue.getInstance(this, MissionNameConstant.MISSION_KLINE);
			List<StrategyFundModel> detectModels = StrategyFundSelDao.getInstance(this).queryStraByOffsetDays(new Date(), -10);
			if (detectModels!=null && !detectModels.isEmpty()){
				for (int i = 0 ; i < detectModels.size(); i++){
					SelfFundHisModel sfHisModel = new SelfFundHisModel(detectModels.get(i));
					kLineMissions.addKLineMissions(sfHisModel);
				}
			}
			kLineMissions.start(this);
		}
	}

	private void reqKeepedPosition() {
		RefreshLogSession.getInstance().refresh(this);
	}

	private void reqMarketStaMission() {
		if (marketStaticMission == null){
			marketStaticMission =  MarketStaticMission.getInstance(this, MissionNameConstant.MISSION_DFCF_STA);
		}
		marketStaticMission.start(this);
	}

	private void reqMoneyFlow() {
		if (moneyFlowStaMission == null){
			moneyFlowStaMission = MoneyFlowStaMission.getInstance(this, MissionNameConstant.MISSION_MONEY_STA);
		}
		moneyFlowStaMission.start(this);
	}


	public void getNewlyFundModels() {
//		fundModels = SelfFundDao.getInstance(this).queryFundModelsExceptType(SelfFundModel.SOURCE_CUSTOMADD);
		if (getBoolSP(this, SharePrefConstants.IS_WANGLONG_REQ, true)){
			fundModels = SelfFundDao.getInstance(this).queryAllSelfFundModes();
		}else{
			fundModels = SelfFundDao.getInstance(this).querySelfFundeModesExceptWanglong();
		}
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

    @Override
    public void executeSuccess(Object result, Mission mission) {
        if (MissionNameConstant.MISSION_BUYXIN.equals(mission.missionName)){
            ToastUtils.showMiddleMsg(this,"打新成功");
        }else if (MissionNameConstant.MISSION_STRATEGY.equals(mission.missionName)){


			ToastUtils.showMiddleMsg(this,"加入策略数据完成");
		}
    }

    @Override
    public void executeFaile(Mission mission) {
        if (MissionNameConstant.MISSION_BUYXIN.equals(mission.missionName)){
            ToastUtils.showMiddleMsg(this,"打新失败");
        }else if (MissionNameConstant.MISSION_STRATEGY.equals(mission.missionName)){
			ToastUtils.showMiddleMsg(this,"加入策略数据失败");
		}
    }

	@Override
	public void getPosition(PositionModel model) {
		ToastUtils.showMiddleMsg(this,"刷新资产信息成功");
	}

	@Override
	public void autoBuyResult(TRADE_ERROR_STATE state, String info) {
		switch (state){
			case ERROR_NOT_NEW_POSITION:
				CurPosition curPosition = new CurPosition();
				curPosition.requset(this);
				break;
		}
//		ToastUtils.showMiddleMsg(this, info);
		NotiUtils.showSimpleNoti(this, NotiIdGenerator.ID_AUTO_BUY, "自动下单:",info,R.drawable.ic_success);
	}

	@Override
	public void resultSuccess() {
		CurPosition curPosition = new CurPosition();
		curPosition.requset(this);
	}

	@Override
	public void resultFaile() {
		CurPosition curPosition = new CurPosition();
		curPosition.requset(this);
	}


	public class LatestPriceServiceBinder extends Binder {

		public LatestPriceService getService() {
			return LatestPriceService.this;
		}
	}

	public void setNetWorkListener(NetWorkListener listener) {
		this.listener = listener;
	}

	public List<SelfFundModel> getFundModels() {
		return fundModels;
	}

	public void setFundModels(List<SelfFundModel> fundModels) {
		this.fundModels = fundModels;
	}
	
	
	@Override
	public void onErrorResponse(VolleyError error, EventBusConstants eventCode) {
		// TODO Auto-generated method stub
		if (eventCode ==EventBusConstants.EVENT_STOCKS_UPDATE_MUTI_PRICE) {
			ToastUtils.showMiddleMsg(this, "Update Price in backGround Faile");
		}
	}

	@Override
	public void onErrorResponse(VolleyError error, String eventCode) {

	}

	@Override
	public void onResponse(String response, EventBusConstants eventCode) {
		// TODO Auto-generated method stub
		if (eventCode == EventBusConstants.EVENT_STOCKS_UPDATE_MUTI_PRICE) {
			ToastUtils.showMiddleMsg(this, "update Price background success\n LoginState:"+FundApplication.isLogSuccess);

			FundAsyTask<String, Void, Void> updateLocPriceTask = new FundAsyTask<String, Void, Void>();
			updateLocPriceTask.backListener = new TaskLitener<String, Void>() {
				//
				@Override
				public Void doInBackground(String... params) {
					// TODO Auto-generated method stub
					fundModels = SelfFundDao.getInstance(LatestPriceService.this).parseSinaMultiPrices(params[0], fundModels);
					
					if (fundModels == null) {
						return null;
					}
					float szCurPrice = 0;

					for (int i = 0; i < fundModels.size(); i++) {
						if (fundModels.get(i).getSourceCode() == SelfFundModel.SOURCE_ZB && SelfFundModel.CODE_SH.equals(fundModels.get(i).getStockNo())) {
							szCurPrice = fundModels.get(i).getCurPrice();
						} else {
							continue;
						}
					}

					for (int i = 0; i < fundModels.size(); i++) {
						// TODO 这里需要加入如果是我的持仓的时候，需要将我的持仓信息加入到里面
						SelfFundModel tmpModel = fundModels.get(i);
						if (tmpModel.getlastClose() == 0 || tmpModel.getCurPrice() == 0 || tmpModel.gethPrice() == 0) {
							// 过滤错误条件
							continue;
						}
						if (tmpModel.getSourceCode() == SelfFundModel.SOURCE_ZB) {
							tmpModel.isRecord = isRecord;
						} else {
							MyAccountStocks ownStock = MyAccountStockDao.getInstance(LatestPriceService.this).queryStock(tmpModel.getStockNo());
							MyOwnStockManager.getInstance(LatestPriceService.this).handlRealStock(tmpModel, ownStock,isRecord);
							
							AIAccountsModel aiStock = AIAccountDao.getInstance(LatestPriceService.this).queryStock(tmpModel.getStockNo());
							MyOwnStockManager.getInstance(LatestPriceService.this).handleAIStock(tmpModel, aiStock);
							
							SelfFundSetModel buySetModel = SelfFundSetDao.getInstance(LatestPriceService.this).needOpSetModel(tmpModel, new Date(), OperateModel.TradeType_BUY);
							if (buySetModel != null) {
								tmpModel.setCurPrice(MyOwnStockManager.getInstance(LatestPriceService.this).getSelfSetModelPrice(buySetModel, tmpModel));
								long stkQty = BuyHelper.getInstance(LatestPriceService.this).getStkQTY(tmpModel.getCurPrice());
								//是否在仓位控制范围
								if (PositionDao.getInstance(LatestPriceService.this).couldBuy(stkQty, tmpModel.getCurPrice(), TradeSetUtils.getPosition(LatestPriceService.this))) {
									//更新仓位信息
									PositionDao.getInstance(LatestPriceService.this).updateCurPosition(OperateModel.TradeType_BUY, stkQty, tmpModel.getCurPrice());
									BuyHelper.getInstance(LatestPriceService.this).buyMyRealStock(tmpModel,buySetModel, buySetModel.isQuickBuy());
									BuyHelper.getInstance(LatestPriceService.this).buyAIStock(tmpModel);
								}
							}

							tmpModel.isRecord = isRecord;
							if (tmpModel.getTradeType() == OperateModel.TradeType_SELL && ownStock == null) {
								// 如果是卖出操作而且我没有持仓,不播报也不弹窗口
								NotiUtils.cancelNoti(LatestPriceService.this, NotiIdGenerator.generate(tmpModel.getStockNo(), NotiIdGenerator.GenerFrom.SELFFUND));
								continue;
							}
						}
						
						if (tmpModel.getSourceCode() == SelfFundModel.SOURCE_WANGLONG) {
							if (getBoolSP(LatestPriceService.this, SharePrefConstants.NOTI_OPERATE_SHOW, false)) {
								NotiUtils.showSelfFundMode(LatestPriceService.this, tmpModel);
							}else {
								NotiUtils.cancelNoti(LatestPriceService.this, NotiIdGenerator.generate(tmpModel.getStockNo(), NotiIdGenerator.GenerFrom.SELFFUND));
							}
						} else {
							NotiUtils.showSelfFundMode(LatestPriceService.this, tmpModel);
						}
					}
					return null;
				}
			};
			
			updateLocPriceTask.execute(response);

			showSettingSta();
		}
	}

	private void showSettingSta() {
		float curPosition = PositionDao.getInstance(this).getCurPositionValue();
		String position = "";
		if (curPosition!=-1){
			position = "当前仓位:"+CaculateUtils.getPercentByFloat(curPosition);
		}
		NotiUtils.showSimpleNoti(this,NotiIdGenerator.ID_SETTING_STA,"设置概况:"+"情绪指标:"+ CaculateUtils.getPercentByFloat(GlobalIndexHelper.getInstance(this).getBuyPercent()),
				position + "  仓位上限(MAX):"+CaculateUtils.getPercentByFloat(GlobalIndexHelper.getInstance(this).getExptectPosition())+
				"\n情绪止盈:"+CaculateUtils.getPercentByFloat(TradeSetUtils.getLossOffset(this, TradeSetUtils.WIN_OFFSET))+
						"情绪止损:"+CaculateUtils.getPercentByFloat(TradeSetUtils.getLossOffset(this, TradeSetUtils.LOSE_OFFSET)),
				R.drawable.ic_market_sta);
	}

	@Override
	public void onResponse(String response, String eventCode) {
		// TODO Auto-generated method stub
	}

	private void reqStaMissions() {
		if (staMissions == null){
			staMissions = new MissionQueue(this, MissionNameConstant.MISSION_QUEUE_STA_ONCE);
		}
		YiMengPositionMission yiMengMission = YiMengPositionMission.getInstance(this, MissionNameConstant.MISSION_YIMENG_POSITION);
		ZDFMission zdfMission = ZDFMission.getInstance(this, MissionNameConstant.MISSION_WENGU_ZDF_STA);
		WanLongStaMission wanLongStaMission = WanLongStaMission.getInstance(this, MissionNameConstant.MISSION_WANGLONG_STA);
		staMissions.addMission(yiMengMission).addMission(zdfMission).addMission(wanLongStaMission);
		staMissions.start(this);
	}

	@Override
	public void onMissionItemSuccess(MissionQueue queue, Mission item, Object successInfo) {
		if (MissionNameConstant.MISSION_YIMENG_POSITION.equals(item.missionName)){
			marketTitle = parseTitle(successInfo);
		}else if(MissionNameConstant.MISSION_WENGU_ZDF_STA.equals(item.missionName)){
			marketContent = parseContent(successInfo);
			NotiUtils.showSimpleNoti(this, NotiIdGenerator.ID_MARKET_STA, marketTitle , marketContent , R.drawable.ic_market_sta);
		}
		queue.executeNextMission(queue, item);
	}

	private String parseContent(Object successInfo) {
		try {
			return ((JSONObject)successInfo).getString("content");
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return "";
	}

	private String parseTitle(Object successInfo) {
		try {
			return ((JSONObject)successInfo).getString("title");
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return "";
	}


	@Override
	public void onMissionItemFaile(MissionQueue queue, Mission item, Object faileInfo) {
		if (MissionNameConstant.MISSION_QUEUE_STA_ONCE.equals(queue.missionName)){

		}
		ToastUtils.showMiddleMsg(this,item.missionName+"执行失败");
		queue.executeNextMission(queue, item);
	}

	@Override
	public void onMissionQueComplete(MissionQueue queue) {
		if (MissionNameConstant.MISSION_QUEUE_STA_ONCE.equals(queue.missionName)){

		}
		ToastUtils.showMiddleMsg(this, queue.missionName+"队列执行完毕");
//		queue.retryAllMission();
	}

	@Override
	public void onMissionQueAllFaile(MissionQueue queue) {
		ToastUtils.showMiddleMsg(this, queue.missionName+"队列执行失败");
		queue.retryAllMission();
	}


}
